`include "define.v"
// Y86 register file: 2W2R, 1T write, 0T read
module regFile (
    /*AUTOARG*/
   // Outputs
   valA, valB,
   // Inputs
   clock, reset, srcA, srcB, dstE, dstM, valE, valM
   );

input           clock;
input           reset;
input   [3:0]   srcA;
input   [3:0]   srcB;
output  [31:0]  valA;
output  [31:0]  valB;
input   [3:0]   dstE;
input   [3:0]   dstM;
input   [31:0]  valE;
input   [31:0]  valM;

/*AUTOWIRE*/
/*AUTOREG*/

reg [31:0] eax, ecx, edx, ebx, esp, ebp, esi, edi;
// read logic
assign valA = (srcA == `REAX) ? eax :
              (srcA == `RECX) ? ecx :
              (srcA == `REDX) ? edx :
              (srcA == `REBX) ? ebx :
              (srcA == `RESP) ? esp :
              (srcA == `REBP) ? ebp :
              (srcA == `RESI) ? esi :
              (srcA == `REDI) ? edi :
              32'h0000_0000;

assign valB = (srcB == `REAX) ? eax :
              (srcB == `RECX) ? ecx :
              (srcB == `REDX) ? edx :
              (srcB == `REBX) ? ebx :
              (srcB == `RESP) ? esp :
              (srcB == `REBP) ? ebp :
              (srcB == `RESI) ? esi :
              (srcB == `REDI) ? edi :
              32'h0000_0000;

// write logic
//`REAX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        eax <= 32'h0000_0000;
    end else if(dstE == `REAX || dstM == `REAX) begin
        eax <= (dstM == `REAX) ? valM : valE;
    end
end

//`RECX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        ecx <= 32'h0000_0000;
    end else if(dstE == `RECX || dstM == `RECX) begin
        ecx <= (dstM == `RECX) ? valM : valE;
    end
end

//`REDX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        edx <= 32'h0000_0000;
    end else if(dstE == `REDX || dstM == `REDX) begin
        edx <= (dstM == `REDX) ? valM : valE;
    end
end

//`REBX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        ebx <= 32'h0000_0000;
    end else if(dstE == `REBX || dstM == `REBX) begin
        ebx <= (dstM == `REBX) ? valM : valE;
    end
end

//`RESP
always @(posedge clock, posedge reset) begin
    if(reset)begin
        esp <= 32'h0000_0000;
    end else if(dstE == `RESP || dstM == `RESP) begin
        esp <= (dstM == `RESP) ? valM : valE;
    end
end

//`REBP
always @(posedge clock, posedge reset) begin
    if(reset)begin
        ebp <= 32'h0000_0000;
    end else if(dstE == `REBP || dstM == `REBP) begin
        ebp <= (dstM == `REBP) ? valM : valE;
    end
end

//`RESI
always @(posedge clock, posedge reset) begin
    if(reset)begin
        esi <= 32'h0000_0000;
    end else if(dstE == `RESI || dstM == `RESI) begin
        esi <= (dstM == `RESI) ? valM : valE;
    end
end

//`REDI
always @(posedge clock, posedge reset) begin
    if(reset)begin
        edi <= 32'h0000_0000;
    end else if(dstE == `REDI || dstM == `REDI) begin
        edi <= (dstM == `REDI) ? valM : valE;
    end
end

endmodule

